<template>
  <el-dialog class="default-dialog" width="1000px" :visible.sync="show" :close-on-click-modal="false" append-to-body>
    <div class="dialog-header" slot="title">{{ dialogTitle }}</div>
    <div class="dialog-body" v-loading="loading">
      <!-- 搜索框 -->
      <div v-if="!readonly" class="amap-search">
        <!-- <el-input id="search" v-model="searchValue" placeholder="请输入内容" @input="onSearchValueChange"></el-input> -->
        <el-autocomplete v-model="searchValue" :fetch-suggestions="querySearchAsync" placeholder="请输入" @select="handleSelect">
          <template slot-scope="{ item }">
            <span class="name" :title="item.formattedAddress">{{ item.formattedAddress }}</span>
          </template>
        </el-autocomplete>
      </div>
      <div class="amap-demo" id="container"></div>
      <!-- 表单 -->
      <el-form class="default-form" :model="dialogForm" ref="dialogForm" :rules="rules" label-width="80px" label-suffix=":">
        <el-form-item class="form-item-whole" label="选中位置">
          <div v-if="marker" class="address-box">
            <div class="address-name">{{ marker.address }}</div>
            <div class="address-location">{{ dialogForm.location }}</div>
          </div>
          <el-tag v-else type="danger">请点击地图选择位置</el-tag>
        </el-form-item>
        <el-form-item class="form-item-whole" label="详细位置">
          <el-input v-model="dialogForm.address" type="textarea" :disabled="readonly" :autosize="{ minRows: 1, maxRows: 3 }" @input="onAddressChange"> </el-input>
        </el-form-item>
      </el-form>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="show = false">{{ readonly ? '关 闭' : '取 消' }}</el-button>
      <el-button v-if="!readonly" type="primary" @click="handSubmit">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
import AMapLoader from '@amap/amap-jsapi-loader'
export default {
  props: {
    // 是否显示弹窗
    visible: {
      type: Boolean,
      default: false,
    },
    // 标题
    dialogTitle: {
      type: String,
      default: '选择位置',
    },
    // 是否只读
    readonly: {
      type: Boolean,
      default: false,
    },
    // 回显的标点和详细信息
    defaultMarker: {
      type: Object,
      default() {
        return null
      },
    },
  },
  data() {
    return {
      mapKey: [
        {
          key: 'b268e01f642b605bfbbc07868ae8ced4', //key
          securityJsCode: '88e0ae02bde4aa10d42fcd36522c833b', //安全密钥
        },
        {
          key: 'b268e01f642b605bfbbc07868ae8ced4', //key
          securityJsCode: '88e0ae02bde4aa10d42fcd36522c833b', //安全密钥
        },
        {
          key: 'b268e01f642b605bfbbc07868ae8ced4', //key
          securityJsCode: '88e0ae02bde4aa10d42fcd36522c833b', //安全密钥
        },
      ],
      loading: false,
      searchValue: '',
      dialogForm: {
        address: '', //地址
        location: '', //经纬度
      },
      rules: {
        // location: [{ required: true, message: '请在地图上选择位置', trigger: 'change' }],
      },
      map: null,
      marker: null,
      mapMarker: null,
    }
  },
  computed: {
    show: {
      get(val) {
        return this.visible
      },
      set(val) {
        this.$emit('update:visible', val)
      },
    },
  },
  created() {
    this.initAMap()
  },
  methods: {
    // 初始化地图
    initAMap() {
      //这里根据自己需要修改，我为了解决太多人调用导致限额，使用了多个key
      this.map?.destroy() // 销毁地图，并清空地图容器
      this.map = null // 地图对象赋值为null
      AMapLoader?.reset() // 重新生成
      // 生成0到5之间的随机整数
      let randomNumber = Math.floor(Math.random() * 6)
      let mapKeyActive = this.mapKey[randomNumber]
      window._AMapSecurityConfig = {
        securityJsCode: mapKeyActive?.securityJsCode ?? '88e0ae02bde4aa10d42fcd36522c833b',
      }
      AMapLoader.load({
        key: mapKeyActive?.key ?? 'b268e01f642b605bfbbc07868ae8ced4', // 申请好的Web端开发者Key，首次调用 load 时必填
        version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
        plugins: ['AMap.Scale'], //需要使用的的插件列表，如比例尺'AMap.Scale'，支持添加多个如：['...','...']
      }).then((AMap) => {
        this.map = new AMap.Map('container', {
          viewMode: '2D',
          zoom: 18, // 初始化地图级别
          center: [106.550483, 29.563707], // 初始化地图中心点位置
        })
        if (!this.readonly) {
          this.mapClick()
        }
        if (this.defaultMarker) {
          let { lng, lat } = this.defaultMarker.location
          let address = this.defaultMarker.address
          this.mapAddress(lng, lat, address)
        }
      })
    },
    // 地图点击事件
    mapClick() {
      this.map.on('click', (ev) => {
        // target 触发事件的对象
        // lnglat  触发事件的地理坐标，AMap.LngLat 类型
        // pixel  触发事件的像素坐标，AMap.Pixel 类型
        // type  触发事件类型
        let { target, lnglat, pixel, type } = ev
        if (lnglat.lng && lnglat.lat) {
          this.mapAddress(lnglat.lng, lnglat.lat)
        }
      })
    },
    // 根据经纬度获取地址信息（逆向地理编码方法）
    mapAddress(lng, lat, repAddress) {
      AMap.plugin('AMap.Geocoder', () => {
        var geocoder = new AMap.Geocoder({
          city: '023', // city 指定进行编码查询的城市，支持传入城市名、adcode 和 citycode
        })
        var lnglat = [lng, lat]
        geocoder.getAddress(lnglat, (status, result) => {
          if (status === 'complete' && result.info === 'OK') {
            // result为对应的地理位置详细信息
            // console.log('result', result)
            let address = result?.regeocode?.formattedAddress ?? ''
            this.addMarker(address, lng, lat, repAddress)
          }
        })
      })
    },
    // 新增点标记
    addMarker(address, lng, lat, repAddress) {
      if (this.mapMarker) {
        this.map.remove(this.mapMarker)
      }
      let marker = {
        address: address,
        location: {
          lng: lng,
          lat: lat,
        },
      }
      let mapMarker = new AMap.Marker({
        position: new AMap.LngLat(lng, lat), //经纬度对象，也可以是经纬度构成的一维数组[116.39, 39.9]
        title: address,
      })
      let newAddress = repAddress ? repAddress.replace(address, '') : ''
      //将创建的点标记添加到已有的地图实例：
      this.map.add(mapMarker)
      this.marker = marker
      this.mapMarker = mapMarker
      this.dialogForm = {
        address: newAddress,
        location: lng + ',' + lat,
      }
      this.map.setCenter([lng, lat])
    },
    // 搜索值改变
    querySearchAsync(queryString, cb) {
      let results = []
      if (queryString) {
        AMap.plugin('AMap.Geocoder', () => {
          var geocoder = new AMap.Geocoder({
            city: '023', // city 指定进行编码查询的城市，支持传入城市名、adcode 和 citycode
          })
          geocoder.getLocation(queryString, (status, result) => {
            if (status === 'complete' && result.info === 'OK') {
              // result中对应详细地理坐标信息
              results = result?.geocodes ?? []
              cb(results)
            } else {
              cb(results)
            }
          })
        })
      } else {
        cb(results)
      }
    },
    // 选择搜索地址
    handleSelect(row) {
      // console.log(row)
      this.mapAddress(row.location.lng, row.location.lat)
      this.map.setCenter([row.location.lng, row.location.lat])
      this.map.setZoom(18)
    },
    // 详细地址值改变
    onAddressChange() {
      if (!this.marker) {
        this.$message.error('请在地图上选择位置后再输入详细位置信息')
        this.dialogForm.address = ''
      }
    },
    // 确定
    handSubmit() {
      this.$refs.dialogForm.validate((value) => {
        if (value) {
          if (this.marker) {
            var data = {
              address: this.marker.address + this.dialogForm.address,
              location: this.marker.location,
            }
            this.$emit('onMarker', data)
            this.show = false
          } else {
            this.$message.error('请在地图上选择位置')
          }
        }
      })
    },
  },
}
</script>
<style lang="scss" scoped>
.dialog-body {
  position: relative;
}
.amap-demo {
  position: relative;
  width: 100%;
  height: 500px;
  z-index: 0;
}
.amap-search {
  position: absolute;
  left: 30px;
  top: 20px;
  z-index: 1;
}
.default-form {
  margin-top: 20px;
}
.name {
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}
 
.address-box {
  width: 100%;
  border-radius: 5px;
  background: #e9e9eb;
  padding: 10px;
  box-sizing: border-box;
  line-height: 20px;
  .address-name {
    font-size: 15px;
    color: #606266;
  }
  .address-location {
    font-size: 14px;
    color: #909399;
  }
}
</style>